import json
import requests


class zapiPullData:

    host = 'https://zapi.ztn.cn/zapi'
    headers = {
        'Content-Type': 'application/json',
        'Authorization': 'Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJ1c2VySWQiOiIiLCJhcHBJZCI6IiIsInVzZXJOYW1lIjoienQyNjUzOSIsImlhdCI6MTczNjk0NDAxMSwiZXhwIjoxNzM2OTUxMjExfQ.kAvivwThehJXdcrBWMeefheJbaRPddVvJ8ruHw9mQG2R4b5hPDdD1tqPrEHVKfuJrP-901eIt68AY5qD-N-a6w'
    }
    serverId = 1387
    def main_func(self):
        self.get_project_list()
        interfaces = self.get_interface(project_id = '160895')
        for interface in interfaces:
            # 获取接口的详细信息
            interface_detail = self.get_interface_detail(interface.get('interface_id'))

            # 将接口详情写入到一个文本文件中
            with open('interfaces_details.txt', 'a', encoding='utf-8') as file:
                # 如果接口详情是字典，转换成字符串再写入
                if isinstance(interface_detail, dict):
                    file.write(json.dumps(interface_detail, indent=4,ensure_ascii=False))  # 将字典格式化为 JSON 字符串



    def get_project_list(self) -> list:
        """
        获取系统中所有项目列表
        """
        with requests.get(self.host + f'/classification/list?serverId={self.serverId}', headers=self.headers) as response:
            data = response.json().get("data")
            return self.recursion_children(data)
    def recursion_children(self, data):
        """
        递归处理 children 列表。如果某个 item 有 children 列表，继续递归遍历。
        """
        items = []
        for item in data:
            children = item.get('children') if item.get('children') else []

            filtration = {
                'project_id': item.get('id'),
                'name': item.get('name'),
                'children': self.recursion_children(children)
            }
            items.append(filtration)
        return items


    def get_interface(self, project_id: str or int, project_name: str = '') -> list:
        """
        获取项目中的所有接口
        """
        current = 1
        all_data = []
        interface_list = []
        while True:
            param = {
                "classificationId": project_id,
                "serverId": self.serverId,
                "type": "PRIVATE",
                "current": current
            }
            with requests.post(self.host + '/interface/getPage', data=json.dumps(param),headers=self.headers) as response:
                data = response.json().get("data")
                records = data.get("records") if data else []

                if not records:  # 如果当前页没有数据，退出循环
                    break

                all_data.extend(records)  # 将当前页的数据添加到 all_data 列表中
                current += 1  # 请求下一页
        for item in all_data:
            interface = {
                "interface_id": item.get("id"),
                "name": item.get("name")
            }
            interface_list.append(interface)

        return interface_list


    def get_interface_detail(self, interface_id: str or int) -> dict:
        """
        获取接口详情
        """
        # TODO: 数据量过大，需要优化执行速度考虑此处需要多线程提高执行速度

        with requests.get(self.host + f'/interface/getById/{interface_id}', headers=self.headers) as response:
            try:
                data = response.json().get("data")
                return self.interfaceData_treating(data)

            except Exception as e:
                print(e)

    def interfaceData_treating(self,item, treenode: str or int = '', project: str = ''):
        while item:
            blindTest_params = {
                "principalUsername": item.get("principalUsername"),
                "principalJobNumber": item.get("principalJobNumber"),
                "name": item.get("name"),
                "path": item.get("path"),
                "method": item.get("method"),
                "file": self.__get_file(item),
                "interface_tag": self.__get_tag(item),
                "request": self.__get_request(item),
                "headers": self.__get_headers(item)
            }
            print(blindTest_params)

            return blindTest_params

    def __get_file(self, data):
        file_value = []
        if data.get("req_body_type") == 'form' and data.get('req_body_form'):
            for item in json.loads(data.get('req_body_form')):
                value_data ={"required":item.get("required", ''), "type": item.get("type", ''), "desc": item.get("desc", '')}
                file_value.append(value_data)
            return file_value
        return file_value

    def __get_tag(self, data):
        return []

    def __get_request(self, data):
        query_value = []
        json_value = []

        if data.get("req_body_type") == 'raw' or (data.get("req_body_type") == 'json' and data.get("req_body_other")):

            # 处理 req_query
            if data.get("req_query") not in ['[]', '']:
                for item in json.loads(data.get("req_query")):
                    query_value.append({
                        "required": item.get("required", ''),
                        "name": item.get("name", ''),
                        "type": item.get("type", ''),
                        "desc": item.get("desc", '')
                    })

            # 处理 req_body_other
            if data.get("req_body_other"):
                try:
                    req_body_other_dict = json.loads(data.get("req_body_other"))
                except json.JSONDecodeError:
                    # 处理无效的 JSON 字符串
                    return {"json": json_value, "data": None, "params": query_value}
                print(req_body_other_dict)
                properties = req_body_other_dict.get("properties", {})
                required = req_body_other_dict.get("required", [])

                # 遍历 properties
                for key, value in properties.items():
                    value_data = {
                        "name": key,
                        "required": '1' if key in required else '0',
                        "format": value.get("format", ''),
                        "type": value.get("type", ''),
                        "desc": value.get("description", '') if value.get("description") else '',
                    }

                    # 如果字段类型为 object，递归处理
                    if value.get("type") == "object":
                        sub_property_data = self.__process_object_properties(value.get("properties", {}), required)
                        value_data["properties"] = sub_property_data

                    json_value.append(value_data)

        return {"json": json_value, "data": None, "params": query_value}

    def __process_object_properties(self, properties, required):
        """递归处理对象的属性"""
        sub_property_data = []
        for sub_key, sub_value in properties.items():
            sub_property_data.append({
                "name": sub_key,
                "required": '1' if sub_key in required else '0',
                "format": sub_value.get("format", ''),
                "type": sub_value.get("type", ''),
                "desc": sub_value.get("description", '') if sub_value.get("description") else ''
            })
        return sub_property_data

    def __get_headers(self, data):
        headers_value = []
        if data.get('req_headers'):
            for item in json.loads(data.get('req_headers')):
                value_data = {
                    "required": item.get("required", ''),
                    "key": item.get("name", ''),
                    "value": item.get("value", '') if item.get("value")  else '',
                    "type": item.get("type", '') if item.get("type") else '',
                    "desc": item.get("desc", '')
                }
                headers_value.append(value_data)
            return headers_value
        return headers_value


class DataGenerator:
    def __init__(self, data:object):
        self.data = data

    def main(self):
        self.__joint_data()

    def __joint_data(self, file=None, requst=None, headers=None):
        """
        拼接成可执行的接口脚本返回
            standard_params: 基准接口参数
            blindTest_params: 盲测接口参数
        """
        pass

    def __dispose_file(self, data):
        pass

    def __dispose_request(self, data):
        pass

    def __dispose_headers(self, data):
        pass

    def __matching(self,item, type):
        """
        针对不同的请求参数类型匹配相应的value
        初始生成正常的入参
        异常的入参：
            1、value必填项为空、非必填为空(null,'')
            2、value边界值(1·,5,15,50,99,200,512,513)
            3、value的字符类型(string,integer,datetime,number,object,array)
            4、value需要填写的值在业务中不存在或不符合使用规则
        接口条件的限制：
            1、金额、数量、经纬度（负数、浮点数验证）
            2、电话号码、邮箱格式、邮编号、文件上传格式、日期格式（格式不符合规范的情况）
        接口业务逻辑验证：
            1、重复操作同一条数据（新增、修改、删除）
            2、使用已经过期的数据
            3、数据权限（没有该数据权限）
            4、时序验证（跨越流程操作数据）
        接口幂等性验证(重复请求)--推荐单独拎出来使用协程集合验证
        接口与数据库交互验证：
            1、检查存库的数据条数多存或少存的情况
            2、检查存库的数据字段漏存或存错的情况
            3、关注更新的接口更新正常（修改、删除）
        接口安全性验证：
            1、SQL注入
            2、xss攻击（string类型字段验证）
            3、垂直越权和水平越权（人工验证）
            4、敏感信息加密（人工验证）
        """
        pass

if __name__ == '__main__':
    zapiPullData().main_func()